package com.spring.nio.service.chat.handler;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.spring.nio.business.file.dto.FileQueryRespDto;
import com.spring.nio.business.file.service.FileService;
import com.spring.nio.business.file.service.dto.FileDto;
import com.spring.nio.business.file.service.param.FileQueryParam;
import com.spring.nio.business.file.service.param.FileUpdateParam;
import com.spring.nio.business.user.constant.UserStatusEnum;
import com.spring.nio.business.user.dto.UserDTO;
import com.spring.nio.business.user.param.UserCreateParam;
import com.spring.nio.business.user.param.UserQueryParam;
import com.spring.nio.business.user.param.UserUpdateParam;
import com.spring.nio.business.user.service.UserService;
import com.spring.nio.common.BasicConstant;
import com.spring.nio.common.YesOrNoEnum;
import com.spring.nio.core.channel.context.ChannelContext;
import com.spring.nio.core.channel.context.SocketChannelContext;
import com.spring.nio.core.channel.handler.AbstractChannelHandler;
import com.spring.nio.core.configuration.NioServerBootstrap;
import com.spring.nio.core.event.handler.AbstractEventHandler;
import com.spring.nio.core.event.handler.WriteEventHandler;
import com.spring.nio.core.event.listener.event.constant.ExceptionEventTypeEnum;
import com.spring.nio.core.event.listener.event.model.ExceptionEventSource;
import com.spring.nio.core.event.model.PacketData;
import com.spring.nio.core.exception.ExceptionManager;
import com.spring.nio.core.server.FileSystemServer;
import com.spring.nio.core.startup.BasicServer;
import com.spring.nio.service.chat.frame.*;
import com.spring.nio.service.file.frame.FileMessageFrame;
import com.spring.nio.service.file.model.FileEndTransportRequest;
import com.spring.nio.service.file.model.FileTransportRequest;
import com.spring.nio.service.file.model.PersonalFileCommon;
import com.spring.nio.service.file.model.PersonalStoreCommon;
import com.spring.nio.service.file.model.structure.FileTransportTaskDTO;
import com.spring.nio.service.protocol.request.file.FileQueryRequest;
import com.spring.nio.service.protocol.request.file.PersonalStoreRefreshRequest;
import com.spring.nio.service.protocol.request.chat.*;
import com.spring.nio.service.protocol.request.monitor.ServiceMonitorRequest;
import com.spring.nio.service.protocol.response.file.FileQueryResponse;
import com.spring.nio.service.protocol.response.file.FileTransportResponse;
import com.spring.nio.service.protocol.response.file.TransportResponse;
import com.spring.nio.service.protocol.response.monitor.ServiceMonitorResponse;
import com.spring.nio.util.FileUtil;
import com.spring.nio.util.LocalTime;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.CollectionUtils;
import java.io.File;
import java.io.IOException;
import java.nio.channels.SocketChannel;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @author: YSFY
 * @date: 2021-03-24 18:38
 * @pacage_name: com.spring.nio.service.chat.handler
 * @class_name: ChatDecodeHandler
 * @description: 基于聊天服务的ChatRealDataHandler处理器
 */
@Slf4j
@SuppressWarnings("all")
public class ChatRealDataHandler extends AbstractChannelHandler {
    private static FileService fileService = null;
    private static UserService userService = null;
    static {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = NioServerBootstrap.getConfig().getClassPathXmlApplicationContext();
        userService = classPathXmlApplicationContext.getBean(UserService.class);
        fileService = classPathXmlApplicationContext.getBean(FileService.class);
    }
    public ChatRealDataHandler() {
        Map<String, Consumer<FunctionParam>> actionMap = AbstractChannelHandler.getActionMap();

        // 服务监控
        actionMap.put(ChatMessageFrame.FrameType.SERVICE_MONITOR.getFrameType(), (functionParam) -> serviceMonitorHandler(functionParam));
        // 文件查询
        actionMap.put(ChatMessageFrame.FrameType.FILE_QUERY_LIST.getFrameType(), (functionParam) -> queryFileListHandler(functionParam));
        // 文件在线传输发起端流结束帧处理
        actionMap.put(ChatMessageFrame.FrameType.FILE_ONLINE_TRANSPORT_SEND_END.getFrameType(), (functionParam) -> fileOnlineStreamEndHandler(functionParam));
        // 文件上传流结束帧处理
        actionMap.put(ChatMessageFrame.FrameType.FILE_UPLOAD_STREAM_END.getFrameType(), (functionParam) -> fileStreamEndHandler(functionParam));
        // 文件上传流取消帧处理
        actionMap.put(ChatMessageFrame.FrameType.FILE_UPLOAD_CANCEL.getFrameType(), (functionParam) -> fileStreamCancelHandler(functionParam));
        // 文件下载流取消帧处理
        actionMap.put(ChatMessageFrame.FrameType.FILE_DOWNLOAD_CANCEL.getFrameType(), (functionParam) -> fileStreamCancelHandler(functionParam));
        // 注册帧
        actionMap.put(ChatMessageFrame.FrameType.REGISTER.getFrameType(), (functionParam) -> registerHandler(functionParam));
        // 登录处理
        actionMap.put(ChatMessageFrame.FrameType.LOGIN.getFrameType(), (functionParam) -> loginHandler(functionParam));
        // 登出处理
        actionMap.put(ChatMessageFrame.FrameType.LOGOUT.getFrameType(), (functionParam) -> logoutHandler(functionParam));
        // 文本消息处理
        actionMap.put(ChatMessageFrame.FrameType.TEXT.getFrameType(), (functionParam) -> textHandler(functionParam));
        // 刷新用户梳理
        actionMap.put(ChatMessageFrame.FrameType.REFRESH.getFrameType(), (functionParam) -> refreshHandler(functionParam));
        // 查询用户处理
        actionMap.put(ChatMessageFrame.FrameType.QUERY_USER.getFrameType(), (functionParam) -> queryUserHandler(functionParam));
        // 心跳处理
        actionMap.put(ChatMessageFrame.FrameType.HEART.getFrameType(), (functionParam) -> heartHandler(functionParam));
        // 个人网盘文件夹刷新帧(刷新子文件夹以及文件列表)
        actionMap.put(ChatMessageFrame.FrameType.PERSONAL_STORE_FILE_REFRESH.getFrameType(), (functionParam) -> personalStoreRefreshHandler(functionParam));
        // 个人网盘文件夹创建处理
        actionMap.put(ChatMessageFrame.FrameType.PERSONAL_STORE_FILE_CREATE.getFrameType(), (functionParam) -> personalStoreCreateHandler(functionParam));
        // 个人网盘文件夹修改处理
        actionMap.put(ChatMessageFrame.FrameType.PERSONAL_STORE_FILE_UPDATE.getFrameType(), (functionParam) -> personalStoreUpdateHandler(functionParam));
        // 个人网盘文件删除处理
        actionMap.put(ChatMessageFrame.FrameType.PERSONAL_FILE_DELETE.getFrameType(), (functionParam) -> personalFileDeleteHandler(functionParam));

    }

    @Override
    public void handler(Object o, ChannelContext channelContext) {
        PacketData packetData = (PacketData) o;
        SocketChannelContext socketChannelContext = packetData.getSocketChannelContext();
        if(CollectionUtils.isEmpty(socketChannelContext.getRealList())) {
            return;
        }

        final FunctionParam functionParam = new FunctionParam();
        functionParam.setSocketChannelContext(socketChannelContext);
        socketChannelContext.getRealList().stream().forEach(obj -> {
            try {
                functionParam.setChatMessageFrame((ChatMessageFrame) obj);
                AbstractChannelHandler.getActionMap().get(functionParam.getChatMessageFrame().getFrameType().getFrameType()).accept(functionParam);
            } catch (Exception e) {
                // 异常事件(ExceptionEvent) 事件源类型为异常事件源类型(EXCEPTION_EVENT_SOURCE)  事件源数据(NioReadEventExceptionSource)
                ExceptionEventSource exceptionEventSource = new ExceptionEventSource();
                exceptionEventSource.setSocketChannelContext(packetData.getSocketChannelContext());
                exceptionEventSource.setModule("FileRealDataHandler --> method [handler] --> 产生异常");
                exceptionEventSource.setException(e);
                exceptionEventSource.setExceptionEventTypeEnum(ExceptionEventTypeEnum.CHAT_BUSINESS_HANDLER_EXCEPTION);
                exceptionEventSource.setIsSend(Boolean.TRUE);
                ExceptionManager.handleException(exceptionEventSource);
            }
        });
    }

    /**
     * 服务监控
     * @param FunctionParam
     * */
    private void serviceMonitorHandler(FunctionParam functionParam) {
        ServiceMonitorRequest serviceMonitorRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), ServiceMonitorRequest.class);

        // 获取当前用户再线传输任务数
        UserQueryParam userQueryParam = new UserQueryParam();
        userQueryParam.setUserId(serviceMonitorRequest.getUserId());
        UserDTO userDto = userService.getOnlineUserById(userQueryParam);

        final ServiceMonitorResponse serviceMonitorResponse = new ServiceMonitorResponse();
        serviceMonitorResponse.setConnectionInfoList(Lists.newArrayList());
        // 记录上传任务数
        if(!CollectionUtils.isEmpty(userDto.getUploadFileMap())) {
            userDto.getUploadFileMap().values().stream().forEach(fileTransportTaskDto -> {
                final ServiceMonitorResponse.ConnectionInfo connectionInfo = new ServiceMonitorResponse.ConnectionInfo();
                connectionInfo.setOperateType("上传");
                connectionInfo.setLocalAddress(fileTransportTaskDto.getSocketChannelContext().getLocalAddress());
                connectionInfo.setRemoteAddress(fileTransportTaskDto.getSocketChannelContext().getRemoteAddress());
                connectionInfo.setFileName(fileTransportTaskDto.getFile().getName());
                connectionInfo.setUploadTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fileTransportTaskDto.getCreateDate()));
                connectionInfo.setBufferSize(String.valueOf(fileTransportTaskDto.getSocketChannelContext().getByteBuffer().capacity()));
                /**
                 * 连接状态最难确定
                 * */
                connectionInfo.setConnectStatus("");
                connectionInfo.setTaskStatus(fileTransportTaskDto.getTaskStatus());
                connectionInfo.setRemark("暂无备注");
                serviceMonitorResponse.getConnectionInfoList().add(connectionInfo);
            });
        }

        // 记录下载任务数
        if(!CollectionUtils.isEmpty(AbstractChannelHandler.fileDownloadThreadMap)) {
            AbstractChannelHandler.fileDownloadThreadMap.values().stream().forEach(map -> {
                FileTransportTaskDTO fileTransportTaskDto = (FileTransportTaskDTO) map.get("TASK");
                final ServiceMonitorResponse.ConnectionInfo connectionInfo = new ServiceMonitorResponse.ConnectionInfo();
                connectionInfo.setOperateType("下载");
                connectionInfo.setLocalAddress(fileTransportTaskDto.getSocketChannelContext().getLocalAddress());
                connectionInfo.setRemoteAddress(fileTransportTaskDto.getSocketChannelContext().getRemoteAddress());
                connectionInfo.setFileName(fileTransportTaskDto.getFile().getName());
                connectionInfo.setUploadTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fileTransportTaskDto.getCreateDate()));
                connectionInfo.setBufferSize(String.valueOf(fileTransportTaskDto.getSocketChannelContext().getByteBuffer().capacity()));
                /**
                 * 连接状态最难确定
                 * */
                connectionInfo.setConnectStatus("");
                connectionInfo.setTaskStatus(fileTransportTaskDto.getTaskStatus());
                connectionInfo.setRemark("暂无备注");
                serviceMonitorResponse.getConnectionInfoList().add(connectionInfo);
            });
        }

        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.SERVICE_MONITOR.getBit());
        transportResponse.setData(serviceMonitorResponse);
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));

        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 向用户 = {} 发送文件服务监控结果数据", serviceMonitorRequest.getUserName());
        WriteEventHandler.addSendData(transportResponse, functionParam.getSocketChannelContext());
    }

    /**
     * 查询文件记录
     * @param FunctionParam
     * */
    private void queryFileListHandler(FunctionParam functionParam) {
        FileQueryRequest fileQueryRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), FileQueryRequest.class);
        FileQueryParam fileQueryParam = new FileQueryParam();
        fileQueryParam.setUserId(fileQueryRequest.getUserId());
        fileQueryParam.setFileName(fileQueryRequest.getFileName());
        try {
            fileQueryRequest.setQueryStartDate(StringUtils.isEmpty(fileQueryRequest.getQueryStartDate())?null:fileQueryRequest.getQueryStartDate().replaceAll("/", "-"));
            fileQueryParam.setQueryStartDate(StringUtils.isEmpty(fileQueryRequest.getQueryStartDate())?null:(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(fileQueryRequest.getQueryStartDate() + " 00:00:00")));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        try {
            fileQueryRequest.setQueryEndDate(StringUtils.isEmpty(fileQueryRequest.getQueryEndDate())?null:fileQueryRequest.getQueryEndDate().replaceAll("/", "-"));
            fileQueryParam.setQueryEndDate(StringUtils.isEmpty(fileQueryRequest.getQueryEndDate())?null:(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(fileQueryRequest.getQueryEndDate() + " 23:59:59")));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        fileQueryParam.setFileType("FILE");
        fileQueryParam.setIsFile(YesOrNoEnum.Y.name());
        fileQueryParam.setIsExist(YesOrNoEnum.Y.name());

        // 查询总记录数
        Integer count = fileService.queryFileListSize(fileQueryParam);

        // 查询记录
        fileQueryParam.setCurrentPage(fileQueryRequest.getCurrentPage());
        fileQueryParam.setPageSize(fileQueryRequest.getPageSize());
        final List<FileQueryRespDto> fileQueryRespDtos = Lists.newArrayList();
        List<FileDto> fileDtos = fileService.queryFileList(fileQueryParam);
        fileDtos.stream().forEach(fileDto -> {
            FileQueryRespDto fileQueryRespDto = new FileQueryRespDto();
            fileQueryRespDto.setId(fileDto.getId());
            fileQueryRespDto.setFileName(fileDto.getFileName());
            fileQueryRespDto.setFileSize(fileDto.getFileSize());
            fileQueryRespDto.setFilePath(fileDto.getFilePath());
            fileQueryRespDto.setFileType(fileDto.getFileType().equals("FILE")?"文件":"文件夹");
            fileQueryRespDto.setUploadTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fileDto.getGmtCreate()));
            fileQueryRespDto.setStatus("已上传");
            fileQueryRespDtos.add(fileQueryRespDto);
        });

        FileQueryResponse fileQueryResponse = new FileQueryResponse();
        fileQueryResponse.setSumCount(count);
        fileQueryResponse.setFileQueryRespDtos(fileQueryRespDtos);
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.FILE_QUERY_LIST.getBit());
        transportResponse.setData(fileQueryResponse);
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));

        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 向用户 = {} 发送文件查询结果数据", fileQueryRequest.getUserName());
        WriteEventHandler.addSendData(transportResponse, functionParam.getSocketChannelContext());
    }

    /**
     * 文件在线传输发起端流结束帧处理
     * @param FunctionParam
     * */
    private void fileOnlineStreamEndHandler(FunctionParam functionParam) {
        FileEndTransportRequest fileEndTransportRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), FileEndTransportRequest.class);
        // 1、关闭掉发起用户和接收用户在服务端的socketChannel，
        // 发起端和接收端的socketChannel关闭原则是：发起端会发送完后自动关闭，接收端也会自动关闭，此时服务端只需关闭发起用户和接收用户所占的uploadMap和downloadMap
        UserQueryParam userQueryParam = new UserQueryParam();
        userQueryParam.setUserId(fileEndTransportRequest.getLaunchUserId());
        UserDTO userDto = userService.getOnlineUserByName(userQueryParam);

        // 2、由于文件流传送帧处理完成，需要释放当前通道对应的读取缓存数据
        AbstractEventHandler.clearChannelCache(functionParam.getSocketChannelContext().getRemoteAddress());
    }

    /**
     * 文件上传流结束帧处理
     * @param FunctionParam
     * */
    private void fileStreamEndHandler(FunctionParam functionParam) {
        FileEndTransportRequest fileEndTransportRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), FileEndTransportRequest.class);
        // 1、结束当前用户文件传送任务
        fileService.finishFileTransportTask(fileEndTransportRequest);
        // 2、由于文件流传送帧处理完成，需要释放当前通道对应的读取缓存数据
        AbstractEventHandler.clearChannelCache(functionParam.getSocketChannelContext().getRemoteAddress());
    }

    /**
     * 文件上传或下载流取消帧处理
     * @param FunctionParam
     * */
    private void fileStreamCancelHandler(FunctionParam functionParam) {
        FileTransportRequest fileTransportRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), FileTransportRequest.class);
        AbstractChannelHandler.cancelFileTransport(fileTransportRequest);
    }

    /**
     * 注册处理,注册成功后由客户端直接发起登录,注册只是短链接
     * @param FunctionParam
     * @return
     * */
    public void registerHandler(FunctionParam functionParam) {
        UserRegisterRequest userRegisterRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), UserRegisterRequest.class);
        // 1、判断当前用户是否已注册，未注册直接注册，已注册告知直接登录
        UserQueryParam userQueryParam = new UserQueryParam();
        userQueryParam.setUserName(userRegisterRequest.getUserName());
        UserDTO userDto = userService.getUserByName(userQueryParam);
        if(Optional.ofNullable(userDto).isPresent()) {
            sendRepeatRegisterMessage(functionParam.getSocketChannelContext().getSocketChannel(), userRegisterRequest, functionParam.getSocketChannelContext());
            return;
        }

        // 2、创建待注册用户
        UserCreateParam userCreateParam = new UserCreateParam();
        userCreateParam.setUserName(userRegisterRequest.getUserName());
        userCreateParam.setPassword(userRegisterRequest.getPassword());
        userCreateParam.setPhone(userRegisterRequest.getPhone());
        userCreateParam.setMail(userRegisterRequest.getMail());
        userCreateParam.setRegister(YesOrNoEnum.Y.name());
        userCreateParam.setRegisterDate(new Date());
        userCreateParam.setLastLoginDate(null);
        userCreateParam.setStatus(UserStatusEnum.REGISTERED.getStatus());
        userDto = userService.create(userCreateParam);
        if(Optional.ofNullable(userDto).isPresent()) {
            sendSuccessRegisterMessage(functionParam.getSocketChannelContext().getSocketChannel(), userDto, functionParam.getSocketChannelContext());
        } else {
            sendFailRegisterMessage(functionParam.getSocketChannelContext().getSocketChannel(), userRegisterRequest, functionParam.getSocketChannelContext());
        }
    }

    /**
     * 登录处理
     * @param FunctionParam
     * */
    private void loginHandler(FunctionParam functionParam) {
        UserLoginRequest userLoginRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), UserLoginRequest.class);
        Map userMap = UserService.onlineUser;
        String remoteAddress = functionParam.getSocketChannelContext().getRemoteAddress();

        // 1、查询数据库判断当前用户是否存在
        UserQueryParam userQueryParam = new UserQueryParam();
        userQueryParam.setUserName(userLoginRequest.getUserName());
        UserDTO userDto = userService.getUserByName(userQueryParam);
        if(Optional.ofNullable(userDto).isPresent()) {

            // 2、判断用户名或密码是否错误
            if(!StringUtils.equals(userLoginRequest.getPassword(), userDto.getPassword())){
                this.sendFailLoginMessage(functionParam.getSocketChannelContext().getSocketChannel(), userLoginRequest, functionParam.getSocketChannelContext(), "密码错误, 登陆失败");
                return;
            }

            // 3、 判断用户是否已登录，内存判断，后期可更改为redis
            if(!CollectionUtils.isEmpty(userMap)) {
                Map<String, List<UserDTO>> onlineUserMap = (new ArrayList<UserDTO>(userMap.values())).stream().collect(Collectors.groupingBy(UserDTO::getUserName));
                if(onlineUserMap.containsKey(userLoginRequest.getUserName())) {
                    // 用户已登录，发送重复登录消息
                    this.sendRepeatLoginMessage(functionParam.getSocketChannelContext().getSocketChannel(), userLoginRequest, functionParam.getSocketChannelContext());
                    return;
                }
            }

            // 4、未登录，db更新用户登录状态
            Date loginSuccessDate = new Date();
            UserUpdateParam userUpdateParam = new UserUpdateParam();
            userUpdateParam.setId(userDto.getId());
            userUpdateParam.setLastLoginDate(loginSuccessDate);
            userUpdateParam.setStatus(UserStatusEnum.ONLINE.getStatus());
            userService.update(userUpdateParam);

            // 5、内存更新用户登录状态
            userDto.setStatus(userUpdateParam.getStatus());
            userDto.setLastLoginDate(userUpdateParam.getLastLoginDate());
            userDto.setChatSocketChannelContext(functionParam.getSocketChannelContext());
            userMap.put(remoteAddress, userDto);

            // 3.3、发送成功登录消息
            this.sendSuccessLoginMessage(functionParam.getSocketChannelContext().getSocketChannel(), userDto, functionParam.getSocketChannelContext(), loginSuccessDate);
            return;
        }

        // 用户不存在,发送登录失败消息
        this.sendFailLoginMessage(functionParam.getSocketChannelContext().getSocketChannel(), userLoginRequest, functionParam.getSocketChannelContext(), "用户不存在, 登陆失败");
    }

    /**
     * 登出处理
     * @param functionParam
     * */
    private void logoutHandler(FunctionParam functionParam) {
        UserLogoutRequest userLogoutRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), UserLogoutRequest.class);
        String remoteAddress = functionParam.getSocketChannelContext().getRemoteAddress();
        userService.offlineUser(remoteAddress, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE);
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] NioServerContext | --> 用户 [{}] 下线成功, 剩余用户数 [{}], remoteAddress = [{}], thread = [{}]",
            userLogoutRequest.getUserName(), UserService.onlineUser.size(), remoteAddress, Thread.currentThread().getName());
        // 发送成功下线消息
        this.sendSuccessLogoutMessage(functionParam.getSocketChannelContext(), userLogoutRequest, functionParam.getSocketChannelContext());
    }

    /**
     * 文本处理
     * @param functionParam
     * */
    private void textHandler(FunctionParam functionParam) {
        MessageTextRequest messageTextRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), MessageTextRequest.class);
        Map userMap = UserService.onlineUser;
        Map<String, List<UserDTO>> onlineUserMap = (new ArrayList<UserDTO>(userMap.values())).stream().collect(Collectors.groupingBy(UserDTO::getUserName));
        // 判断远程用户是否存在，存在则获取其socketChannel并发送数据
        if(onlineUserMap.containsKey(messageTextRequest.getRemoteUserName())) {
            // 获取对方用户
            UserDTO userDto = ((UserDTO) (((List<UserDTO>) onlineUserMap.get(messageTextRequest.getRemoteUserName())).get(0)));
            // 获取对方用户的socketChannelContext
            this.sendChatSuccessMessage(messageTextRequest, userDto.getChatSocketChannelContext());
            return;
        } else {
            this.sendChatFailMessage(functionParam.getSocketChannelContext().getSocketChannel(), messageTextRequest, functionParam.getSocketChannelContext());
        }
    }

    /**
     * 刷新在线用户
     * @param functionParam
     * */
    private void refreshHandler(FunctionParam functionParam) {
        MessageRefreshRequest messageRefreshRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), MessageRefreshRequest.class);
        Map userMap = UserService.onlineUser;

        // 获取所有在线用户(从内存中读取)
        List<UserDTO> onlineUsers = (new ArrayList<UserDTO>(userMap.values())).stream().filter(predict -> (predict.getStatus().equals(UserStatusEnum.ONLINE.getStatus())) && (!StringUtils.equals(messageRefreshRequest.getUserName(), predict.getUserName()))).collect(Collectors.toList());

        // 构造发送数据
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.REFRESH.getBit());
        transportResponse.setData(onlineUsers);

        // 发送数据
        WriteEventHandler.addSendData(transportResponse, functionParam.getSocketChannelContext());
    }

    /**
     * 搜索用户帧
     * @param functionParam
     */
    private void queryUserHandler(FunctionParam functionParam) {
        UserQueryRequest userQueryRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), UserQueryRequest.class);
        UserQueryParam userQueryParam = new UserQueryParam();
        userQueryParam.setUserName(userQueryRequest.getQueryUser());
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.QUERY_USER.getBit());
        transportResponse.setData(userService.getFuzzyQueryUserByName(userQueryParam));
        WriteEventHandler.addSendData(transportResponse, functionParam.getSocketChannelContext());
    }

    /**
     * 心跳帧
     * @param functionParam
     */
    private void heartHandler(FunctionParam functionParam) {
        MessageHeartRequest messageHeartRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), MessageHeartRequest.class);
        // 打印客户端心跳帧
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> receive client heart frame, userName = {}, interval = {}, data = {}, address = {}, thread = {}",
            messageHeartRequest.getUserName(), messageHeartRequest.getHeartInterval(), messageHeartRequest.getData(), functionParam.getSocketChannelContext().getRemoteAddress(), Thread.currentThread().getName());

        // 发送心跳响应帧
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.HEART.getBit());
        transportResponse.setLaunchUserName(messageHeartRequest.getUserName());
        transportResponse.setMessage("HEART_RESPONSE");
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));
        WriteEventHandler.addSendData(transportResponse, functionParam.getSocketChannelContext());
    }

    /**
     * 个人网盘文件夹刷新帧
     * @param functionParam
     */
    private void personalStoreRefreshHandler(FunctionParam functionParam) {
        PersonalStoreRefreshRequest personalStoreRefreshRequest = JSON.parseObject(functionParam.getChatMessageFrame().getData(), PersonalStoreRefreshRequest.class);
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> receive client personal folder store refresh frame, address = {}, thread = {}", functionParam.getSocketChannelContext().getRemoteAddress(), Thread.currentThread().getName());

        // 获取个人网盘文件夹信息
        // 判断操作系统类型， 获取个人文件路径  完整路径和相对路径
        String completeFilePath = "", relativeFilePath = FileUtil.formatFileSepartor(personalStoreRefreshRequest.getFilePath() + File.separator);
        if(BasicServer.getMap().get(BasicConstant.OS_NAME).toString().contains("Win")) { // win
            completeFilePath = BasicServer.getMap().get(BasicConstant.NIO_FILE_BASE_PATH_WINDOWS).toString() + personalStoreRefreshRequest.getFilePath();
            if(!personalStoreRefreshRequest.getFilePath().endsWith(File.separator)) {
                completeFilePath += File.separator;
            }
        } else { // linux or Mac
            completeFilePath = BasicServer.getMap().get(BasicConstant.NIO_FILE_BASE_PATH_LINUX_MAC).toString() + personalStoreRefreshRequest.getFilePath();
            if(!personalStoreRefreshRequest.getFilePath().endsWith(File.separator)) {
                completeFilePath += File.separator;
            }
        }

        // 查询当前文件夹文件夹信息
        FileQueryParam fileQueryParam = new FileQueryParam();
        fileQueryParam.setPId(StringUtils.isBlank(personalStoreRefreshRequest.getPId())?-1:Long.valueOf(personalStoreRefreshRequest.getPId()));
        fileQueryParam.setUserId(personalStoreRefreshRequest.getUserId());
        fileQueryParam.setFileName(personalStoreRefreshRequest.getFileName());
        fileQueryParam.setFileType(personalStoreRefreshRequest.getFileType());
        fileQueryParam.setIsFile(YesOrNoEnum.N.name());
        fileQueryParam.setIsExist(YesOrNoEnum.Y.name());
        fileQueryParam.setCurrentPage(personalStoreRefreshRequest.getCurrentPage());
        fileQueryParam.setPageSize(personalStoreRefreshRequest.getPageSize());

        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.PERSONAL_STORE_FILE_REFRESH.getBit());
        transportResponse.setUserId(personalStoreRefreshRequest.getUserId());
        transportResponse.setLaunchUserName(personalStoreRefreshRequest.getUserName());
        transportResponse.setData(fileService.getFolderFileTree(fileQueryParam, completeFilePath, relativeFilePath));
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));
        WriteEventHandler.addSendData(transportResponse, functionParam.getSocketChannelContext());
    }

    /**
     * 个人网盘文件夹创建帧
     * @param functionParam
     */
    private void personalStoreCreateHandler(FunctionParam functionParam) {
        PersonalStoreCommon personalStoreCommon = JSON.parseObject(functionParam.getChatMessageFrame().getData(), PersonalStoreCommon.class);
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 接受到客户端个人网盘创建文件夹帧, userName = {}, address = {}", personalStoreCommon.getUserName(), functionParam.getSocketChannelContext().getRemoteAddress());

        // 获取个人网盘文件夹信息
        // 判断操作系统类型， 获取个人文件路径
        String completeFilePath = "", relativeFilePath = FileUtil.formatFileSepartor(personalStoreCommon.getFilePath() + personalStoreCommon.getNewFileName() + File.separator);
        if(BasicServer.getMap().get(BasicConstant.OS_NAME).toString().contains("Win")) { // win
            completeFilePath = BasicServer.getMap().get(BasicConstant.NIO_FILE_BASE_PATH_WINDOWS).toString() + personalStoreCommon.getFilePath() + File.separator;
            if(!personalStoreCommon.getNewFileName().equals("")) {
                completeFilePath += personalStoreCommon.getNewFileName() + File.separator;
            }
        } else { // linux or Mac
            completeFilePath = BasicServer.getMap().get(BasicConstant.NIO_FILE_BASE_PATH_LINUX_MAC).toString() + personalStoreCommon.getFilePath() + File.separator;
            if(!personalStoreCommon.getNewFileName().equals("")) {
                completeFilePath += personalStoreCommon.getNewFileName() + File.separator;
            }
        }

        // 文件系统创建
        if(!FileSystemServer.createFolder(completeFilePath)) {
            log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 个人网盘创建文件夹失败, userName = {}, address = {}", personalStoreCommon.getUserName(), functionParam.getSocketChannelContext().getRemoteAddress());
            return;
        }

        // 创建文件夹信息DB记录
        FileQueryParam fileQueryParam = new FileQueryParam();
        fileQueryParam.setPId(personalStoreCommon.getId());
        fileQueryParam.setFileName(personalStoreCommon.getNewFileName());
        fileQueryParam.setUserId(personalStoreCommon.getUserId());
        fileQueryParam.setFilePath(relativeFilePath);
        fileQueryParam.setFileSize(personalStoreCommon.getFileSize());
        fileQueryParam.setFileType(personalStoreCommon.getFileType());
        fileQueryParam.setIsFile(YesOrNoEnum.N.name());
        fileQueryParam.setIsExist(YesOrNoEnum.Y.name());

        // 发送文件夹创建成功帧
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.PERSONAL_STORE_FILE_CREATE.getBit());
        transportResponse.setLaunchUserName(personalStoreCommon.getUserName());
        transportResponse.setData(fileService.create(fileQueryParam, completeFilePath));
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));
        WriteEventHandler.addSendData(transportResponse, functionParam.getSocketChannelContext());
    }

    /**
     * 个人网盘文件夹修改帧
     * @param functionParam
     */
    private void personalStoreUpdateHandler(FunctionParam functionParam) {
        PersonalStoreCommon personalStoreCommon = JSON.parseObject(functionParam.getChatMessageFrame().getData(), PersonalStoreCommon.class);
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 接受到客户端个人网盘修改文件夹帧, userName = {}, address = {}",
            personalStoreCommon.getUserName(), functionParam.getSocketChannelContext().getRemoteAddress());

        // 获取个人网盘文件夹信息
        // 判断操作系统类型， 获取个人文件路径
        String completeFilePath = "", orginFilePath = "", newRelativeFilePath = "";
        if(BasicServer.getMap().get(BasicConstant.OS_NAME).toString().contains("Win")) { // win
            completeFilePath = BasicServer.getMap().get(BasicConstant.NIO_FILE_BASE_PATH_WINDOWS).toString() + personalStoreCommon.getFilePath() + File.separator;

            // 构建原始文件夹全路径
            orginFilePath = completeFilePath;

            // 构建新文件夹相对路径
            int relativePostion = personalStoreCommon.getFilePath().lastIndexOf(personalStoreCommon.getOriginFileName());
            newRelativeFilePath = personalStoreCommon.getFilePath().substring(0, relativePostion);
            newRelativeFilePath += personalStoreCommon.getNewFileName() + File.separator;

            // 构建新文件夹全路径
            int position = completeFilePath.lastIndexOf(personalStoreCommon.getOriginFileName());
            completeFilePath = completeFilePath.substring(0, position);
            completeFilePath += personalStoreCommon.getNewFileName() + File.separator;
        } else { // linux or Mac
            completeFilePath = BasicServer.getMap().get(BasicConstant.NIO_FILE_BASE_PATH_LINUX_MAC).toString()
                + personalStoreCommon.getFilePath() + File.separator;

            // 构建原始文件夹全路径
            orginFilePath = completeFilePath;

            // 构建新文件夹相对路径
            int relativePostion = personalStoreCommon.getFilePath().lastIndexOf(personalStoreCommon.getOriginFileName());
            newRelativeFilePath = personalStoreCommon.getFilePath().substring(0, relativePostion);
            newRelativeFilePath += personalStoreCommon.getNewFileName() + File.separator;

            // 构建新文件夹全路径
            int position = completeFilePath.lastIndexOf(personalStoreCommon.getOriginFileName());
            completeFilePath = completeFilePath.substring(0, position);
            completeFilePath += personalStoreCommon.getNewFileName() + File.separator;
        }

        // 修改文件夹信息
        FileUpdateParam fileUpdateParam = new FileUpdateParam();
        fileUpdateParam.setId(personalStoreCommon.getId());
        fileUpdateParam.setFileName(personalStoreCommon.getNewFileName());
        fileUpdateParam.setFilePath(newRelativeFilePath);

        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.PERSONAL_STORE_FILE_UPDATE.getBit());
        transportResponse.setUserId(personalStoreCommon.getUserId());
        transportResponse.setLaunchUserName(personalStoreCommon.getUserName());
        transportResponse.setData(fileService.update(fileUpdateParam, orginFilePath, completeFilePath));
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));
        WriteEventHandler.addSendData(transportResponse, functionParam.getSocketChannelContext());
    }

    /**
     * 个人网盘文件删除帧
     * @param functionParam
     */
    private void personalFileDeleteHandler(FunctionParam functionParam) {
        PersonalFileCommon personalFileCommon = JSON.parseObject(functionParam.getChatMessageFrame().getData(), PersonalFileCommon.class);
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 接受到客户端个人网盘删除文件夹帧, userName = {}, address = {}",
            personalFileCommon.getUserName(), functionParam.getSocketChannelContext().getRemoteAddress());

        // 1、判断操作系统类型， 获取个人文件路径
        String osName = BasicServer.getMap().get(BasicConstant.OS_NAME).toString();
        String rootFilePath = osName.contains("Win")?BasicServer.getMap().get(BasicConstant.NIO_FILE_BASE_PATH_WINDOWS).toString():BasicServer.getMap().get(BasicConstant.NIO_FILE_BASE_PATH_LINUX_MAC).toString();

        // 2、解析文件操作
        List<Long> fileIdList = Lists.newArrayList();
        //String[] fileNameArray = personalFileCommon.getFileNames().contains(",")?personalFileCommon.getFileNames().split(","):new String[] {personalFileCommon.getFileNames()};
        String[] filePathArray = personalFileCommon.getFilePaths().contains(",")?personalFileCommon.getFilePaths().split(","):new String[] {personalFileCommon.getFilePaths()};
        String[] fileTagArray = personalFileCommon.getTags().contains(",")?personalFileCommon.getTags().split(","):new String[] {personalFileCommon.getTags()};
        for(int i = 0; i < filePathArray.length; i++) {
            String currentFilePath = rootFilePath + filePathArray[i];

            // 判断当前文件是否存在，存在则删除，不考虑文件不存在的情况
            File file = new File(currentFilePath);
            if(file.exists()) {
                if(file.delete()) {
                    // 文件删除成功
                    fileIdList.add(Long.valueOf(fileTagArray[i]));
                }

                // 文件存在，且未删除成功，则不能更新DB del状态，此处不进行文件id追加
            } else {
                // 文件不存在，但是表格却显示出已删除的文件信息，那只记录当前文件id，用于更新数据库，并响应客户端从表格中删除已经不存在的文件对应的行记录
                fileIdList.add(Long.valueOf(fileTagArray[i]));
            }
        }

        // 执行文件删除状态批量更新
        FileQueryParam fileQueryParam = new FileQueryParam();
        fileQueryParam.setId(personalFileCommon.getFolderId());
        fileQueryParam.setIsFile(YesOrNoEnum.N.name());
        fileQueryParam.setIsExist(YesOrNoEnum.Y.name());
        fileService.deleteFile(fileQueryParam, fileIdList);

        FileTransportResponse fileTransportResponse = new FileTransportResponse();
        fileTransportResponse.setResponseName(BasicConstant.FILE_FRAME);
        fileTransportResponse.setCode("200");
        fileTransportResponse.setFrameType(ChatMessageFrame.FrameType.PERSONAL_FILE_DELETE.getBit());
        fileTransportResponse.setLaunchUserName(personalFileCommon.getUserName());
        fileTransportResponse.setData(fileIdList);
        fileTransportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));
        WriteEventHandler.addSendData(fileTransportResponse, functionParam.getSocketChannelContext());
    }

    /**
     * 发送成功注册消息
     * @param socketChannel
     * @param userRegisterRequest
     * @param o
     * */
    private void sendSuccessRegisterMessage(SocketChannel socketChannel, UserDTO userDto, Object o) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.REGISTER.getBit());
        transportResponse.setUserId(userDto.getId());
        transportResponse.setLaunchUserName(userDto.getUserName());
        transportResponse.setMessage("注册成功");
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 用户名 = [{}] 注册成功", userDto.getUserName());
        WriteEventHandler.addSendData(transportResponse, o);
    }

    /**
     * 发送重复注册消息
     * @param socketChannel
     * @param userRegisterRequest
     * @param o
     * */
    private void sendRepeatRegisterMessage(SocketChannel socketChannel, UserRegisterRequest userRegisterRequest, Object o) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.REGISTER.getBit());
        transportResponse.setLaunchUserName(userRegisterRequest.getUserName());
        transportResponse.setMessageType("REPEAT");
        transportResponse.setMessage("[ " + userRegisterRequest.getUserName() + " ] 已存在, 禁止重复注册");
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 用户名 = [{}] 重复注册", userRegisterRequest.getUserName());
        WriteEventHandler.addSendData(transportResponse, o);
    }

    /**
     * 发送注册失败消息
     * @param socketChannel
     * @param chatMessageLogout
     * @param o
     * */
    private void sendFailRegisterMessage(SocketChannel socketChannel, UserRegisterRequest userRegisterRequest, Object o) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.REGISTER.getBit());
        transportResponse.setLaunchUserName(userRegisterRequest.getUserName());
        transportResponse.setMessage("注册失败");
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));

        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 用户名 = [{}] 注册失败", userRegisterRequest.getUserName());
        WriteEventHandler.addSendData(transportResponse, o);
    }

    /**
     * 发送成功登录消息
     * @param socketChannel
     * @param userLoginRequest
     * @param o
     * */
    private void sendSuccessLoginMessage(SocketChannel socketChannel, UserDTO userDto, Object o, Date loginSuccessDate) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.LOGIN.getBit());
        transportResponse.setUserId(userDto.getId());
        transportResponse.setLaunchUserName(userDto.getUserName());
        transportResponse.setMessage("登录成功");
        transportResponse.setTime(Timestamp.valueOf(BasicConstant.SDF.format(loginSuccessDate)));

        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 用户名 = [{}] 登录成功", userDto.getUserName());
        WriteEventHandler.addSendData(transportResponse, o);
    }

    /**
     * 发送重复登录消息
     * @param socketChannel
     * @param userLoginRequest
     * @param o
     * */
    private void sendRepeatLoginMessage(SocketChannel socketChannel, UserLoginRequest userLoginRequest, Object o) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.LOGIN.getBit());
        transportResponse.setLaunchUserName(userLoginRequest.getUserName());
        transportResponse.setMessage("禁止重复登录");
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));

        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 用户名 = {} 重复登录", userLoginRequest.getUserName());
        WriteEventHandler.addSendData(transportResponse, o);
    }

    /**
     * 发送登录失败消息
     * @param socketChannel
     * @param userLoginRequest
     * @param o
     * */
    private void sendFailLoginMessage(SocketChannel socketChannel, UserLoginRequest userLoginRequest, Object o, String message) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.LOGIN.getBit());
        transportResponse.setLaunchUserName(userLoginRequest.getUserName());
        transportResponse.setMessage(message);
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));

        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 用户名 = {} 登陆失败", userLoginRequest.getUserName());
        WriteEventHandler.addSendData(transportResponse, o);
    }

    /**
     * 发送登出失败消息
     * @param socketChannel
     * @param userLogoutRequest
     * @param o
     * */
    private void sendFailLogoutMessage(SocketChannel socketChannel, UserLogoutRequest userLogoutRequest, Object o) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.LOGOUT.getBit());
        transportResponse.setLaunchUserName(userLogoutRequest.getUserName());
        transportResponse.setMessage("下线失败");
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 用户名 = {} 下线失败", userLogoutRequest.getUserName());
        WriteEventHandler.addSendData(transportResponse, o);
    }

    /**
     * 发送成功登出消息
     * @param socketChannelContext
     * @param userLogoutRequest
     * @param o
     * */
    private void sendSuccessLogoutMessage(SocketChannelContext socketChannelContext, UserLogoutRequest userLogoutRequest, Object o) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.LOGOUT.getBit());
        transportResponse.setLaunchUserName(userLogoutRequest.getUserName());
        transportResponse.setMessage("下线成功");
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));

        // 1、向客户端发送下线成功的消息
        WriteEventHandler.addSendData(transportResponse, o);

        // 2、下线操作，释放用户资源，但不关闭当前socketChannel连接，因为有可能以当前SocketChannel重新登录或是登录其他用户，只有关闭了客户端才关闭当前SocketChannel
        /*Boolean result = NioUtil.handleSubReactor(socketChannelContext.getRemoteAddress(), Boolean.FALSE);
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> [{}] {}, remoteAddress = {}, thread = {}",
            String.valueOf(map.get("userName")), (result.equals(Boolean.TRUE)?"下线成功":"下线失败"), socketChannelContext.getRemoteAddress(), Thread.currentThread().getName());*/
    }

    /**
     * 发送成功聊天消息
     * @param socketChannel
     * @param messageTextRequest
     * @param o
     * */
    private void sendChatSuccessMessage(MessageTextRequest messageTextRequest, Object o) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.TEXT.getBit());
        transportResponse.setLaunchUserName(messageTextRequest.getCurrentUserName());
        transportResponse.setMessage(messageTextRequest.getContent());
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));

        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 向用户 = {} 发送 content = {} 数据成功", messageTextRequest.getCurrentUserName(), messageTextRequest.getContent());
        WriteEventHandler.addSendData(transportResponse, o);
    }

    /**
     * 发送聊天失败消息
     * @param socketChannel
     * @param messageTextRequest
     * @param o
     * */
    private void sendChatFailMessage(SocketChannel socketChannel, MessageTextRequest messageTextRequest, Object o) {
        TransportResponse transportResponse = new TransportResponse();
        transportResponse.setCode("200");
        transportResponse.setFrameType(ChatMessageFrame.FrameType.TEXT.getBit());
        transportResponse.setLaunchUserName(messageTextRequest.getRemoteUserName());
        transportResponse.setMessage("用户已下线,请尝试刷新列表");
        transportResponse.setTime(Timestamp.valueOf(LocalDateTime.now()));
        log.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ] ChatRealDataHandler | --> 用户 = {} 已下线, 请尝试刷新列表", messageTextRequest.getCurrentUserName());
        WriteEventHandler.addSendData(transportResponse, o);
        //CoreServerContext.sendMessage(socketChannel, BasicConstant.NIO_SERVER_MAIN_CORE_CHAT_SELECTOR_THREAD, o);
    }
}
